/*
 * $Id: SkvList.cc,v 1.2 2005-05-01 06:38:53 bacon Exp $
 */

#include <xpp/utl/SkvList.h>
#include <xp/bas/assert.h>

namespace xpp
{
	namespace utl
	{

		///////////////
		// SkvSctn //
		///////////////
		
		SkvPair* SkvSctn::addPair (const xp_char_t* key)
		{
			xp_assert (!pairExists(key));
			//if (pairExists(key)) return XP_NULL;
		
			return &append (SkvPair(key));
			/*
			SkvPair& pair = append ();
			pair.key = key;
			return &pair;
			*/
		}

		int SkvSctn::removePair (const xp_char_t* key)
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvPair& pair = np->value;
				if (pair.key == key) {
					remove (np);
					return 0;
				}
			}
			return -1;
		}

		SkvPair* SkvSctn::findPair (const xp_char_t* key) const
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvPair& pair = np->value;
				if (pair.key == key) return &pair;
			}
			return XP_NULL;
		}
		bool SkvSctn::pairExists (const xp_char_t* key) const
		{
			return findPair(key) != XP_NULL;
		}

		xp_char_t* SkvSctn::valueOf (const xp_char_t* key) const
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvPair& pair = np->value;
				if (pair.key == key) {
					return pair.value.buffer();
				}
			}
			return XP_NULL;
		}

		SkvPair* SkvSctn::setValue (const xp_char_t* key, const xp_char_t* val)
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvPair& pair = np->value;
				if (pair.key == key) {
					pair.value = val;
					return &pair;
				}	
			}
		
			/*
			SkvPair& pair = append ();
			pair.key = key;
			pair.value = val;
			return &pair;
			*/
			return &append (SkvPair (key, val));
		}
		
		///////////////
		// SkvList //
		///////////////
		SkvSctn* SkvList::addSection (const xp_char_t* sctn)
		{
			xp_assert (!sectionExists(sctn));
			//if (sectionExists(sctn)) return XP_NULL;
		
			/*
			SkvSctn& s = append ();
			s.setName (sctn);
			return &s;
			*/
			return &append (SkvSctn (sctn));
		}

		SkvPair* SkvList::addPair (const xp_char_t* sctn, const xp_char_t* key)
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvSctn& s = np->value;
				if (s.isNamed(sctn)) return s.addPair (key);
			}
		
			SkvSctn* sp = addSection (sctn);
			return sp->addPair (key);
			//return XP_NULL;
		}
		
		int SkvList::removeSection (const xp_char_t* sctn)
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvSctn& s = np->value;
				if (s.isNamed(sctn)) {
					remove (np);
					return 0;
				}
			}
			return -1;
		}

		int SkvList::removePair (const xp_char_t* sctn, const xp_char_t* key)
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvSctn& s = np->value;
				if (s.isNamed(sctn)) return s.removePair (key);
			}
			return -1;
		}
		
		SkvSctn* SkvList::findSection (const xp_char_t* sctn) const
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvSctn& s = np->value;
				if (s.isNamed(sctn)) return &s;
			}
			return XP_NULL;
		}

		SkvPair* SkvList::findPair (
			const xp_char_t* sctn, const xp_char_t* key) const
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvSctn& s = np->value;
				if (s.isNamed(sctn)) return s.findPair (key);
			}
			return XP_NULL;
		}

		bool SkvList::sectionExists (const xp_char_t* sctn) const
		{
			return findSection (sctn) != XP_NULL;
		}

		bool SkvList::pairExists (const xp_char_t* sctn, const xp_char_t* key) const
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvSctn& s = np->value;
				if (s.isNamed(sctn)) return s.pairExists (key);
			}
			return false;
		}

		xp_char_t* SkvList::valueOf (
			const xp_char_t* sctn, const xp_char_t* key) const
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvSctn& s = np->value;
				if (s.isNamed(sctn)) return s.valueOf (key);
			}
			return XP_NULL;
		}

		SkvSctn* SkvList::setValue (
			const xp_char_t* sctn, const xp_char_t* key, const xp_char_t* val)
		{
			for (Node* np = head(); np; np = np->forward()) {
				SkvSctn& s = np->value;
				if (s.isNamed(sctn)) {
					s.setValue (key, val);
					return &s;
				}
			}
		
			/*
			SkvSctn& s = append ();
			s.setName (sctn);
			s.setValue (key, val);
			return &s;
			*/
			SkvSctn& s = append (SkvSctn (sctn));
			s.setValue (key, val);
			return &s;
		}

	}		
}
